package com.iqiyi.pps.epg.core.async;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
 * Created by karkarrotxu on 2015/12/2.
 * 引用
 */
public class HeartBeatCenter {
    private HeartBeatCenter(){}
    private final static long INTERVAL = 160;
    private final static TimeUnit UNIT = TimeUnit.MILLISECONDS;
    private final static ScheduledExecutorService service = Executors
            .newScheduledThreadPool(1);

    private final static CopyOnWriteArrayList<IHeartBeat> tasks = new CopyOnWriteArrayList<IHeartBeat>();
    private static final Logger logger = LoggerFactory.getLogger(HeartBeatCenter.class);
    private static long errorCount = 0;
    static {
        schedule(new Runnable() {
            @Override
            public void run() {
                try {
                    if(errorCount > 1000){
                        logger.info("errorCount = {}",errorCount);
                    }
                    tick();
                } catch (NullPointerException npe){
                    logger.error("npe = {}",npe);
                    errorCount++;
                }catch (Exception e) {
                    logger.error("exception = {}",e);
                    errorCount++;
                }

            }
        }, System.currentTimeMillis() + 1000, INTERVAL);
    }

    private static void schedule(Runnable command, long scheduledAt, long delay) {
        long now = System.currentTimeMillis();
        if (scheduledAt <= now) {
            scheduledAt += 86400000L;
        }
        service.scheduleWithFixedDelay(command, scheduledAt - now, delay, UNIT);
    }

    private static void tick() {
        long now = System.currentTimeMillis();
        Iterator<IHeartBeat> ite = tasks.iterator();
        while (ite.hasNext()) {
            try{
                ite.next().tick(now);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 注册心跳循环服务
     *
     * @param task
     */
    public static void add(IHeartBeat task) {
        tasks.add(task);
    }

}
